﻿using System;
using System.Net;
using ZyGames.Framework.Game.Service;
using ZyGames.Framework.RPC.Sockets;
using System.Web;
using ZyGames.Framework.Common.Serialization;
using GameServer.Script.Model;
using System.Net.Sockets;
namespace ZyGames.Framework.Game.Contract
{
    public class CustomActionDispatcher : ScutActionDispatcher
    {
        public override ActionGetter GetActionGetter(RequestPackage package, GameSession session)
        {
            Console.WriteLine("RequestPackage 实例解析成功 开始适配http结构");
            int i = 0;
            if (package.Params != null)
            {
                foreach (var item in package.Params)
                {
                    Console.WriteLine("尝试获取请求包package Params[2]<key,value>=<{0},{1}> ", item.Key, item.Value, i);
                    i++;
                }
            }
            else
            {
                package.Params = new System.Collections.Generic.Dictionary<string, string>();
                package.Params.Add("MsgId", package.MsgId.ToString());
                package.Params.Add("ActionId", package.ActionId.ToString());
              
                Console.WriteLine("package 构造解析成功 开始适配http结构");
                foreach (var item in package.Params)
                {
                    Console.WriteLine("尝试获取请求包package Params[2]<key,value>=<{0},{1}> ", item.Key, item.Value, i);
                    i++;
                }


            }
            return base.GetActionGetter(package, session);

        }
        
        public override bool TryDecodePackage(ConnectionEventArgs e, out RequestPackage package)
        {
          
            Console.WriteLine("socket 获得client 的bytes数据");
            Console.WriteLine("尝试获取请求Data.length ：{0}", e.Data.Length);
            Console.WriteLine("尝试获取请求message.data ：{0}", e.Meaage.Data.Length);
            Console.WriteLine("尝试获取请求message.message ：{0}", e.Meaage.Message);
            Console.WriteLine("尝试获取请求socket.RemoteEndPoint ：{0}", e.Socket.RemoteEndPoint);

            Console.WriteLine("尝试解析数据 到 RequestPackage 实例");
            byte[] bytes;
            MessagePack pack = ReadMessageHead(e.Data, out bytes);
            if (pack != null)
            {
                package = new RequestPackage(pack.MsgId, pack.SessionId, pack.ActionId, pack.UserId);
                package.Message = bytes;

                Console.WriteLine("解析成功 RequestPackage 实例MsgId<<{0}", pack.MsgId);
                Console.WriteLine("解析成功 RequestPackage 实例SessionId<<{0}", pack.SessionId);
                Console.WriteLine("解析成功 RequestPackage 实例ActionId<<{0}", pack.ActionId);
                Console.WriteLine("解析成功 RequestPackage 实例UserId<<{0}", pack.UserId);
               
                return true;
            }
            else
                package = new RequestPackage();
            return false;
        
            //return base.TryDecodePackage(e, out package);
        }

        private MessagePack ReadMessageHead(byte[] data, out byte[] content)
        {
            MessagePack headPack = null;
            content = new byte[0];
            try
            {
                //解头部(解之前当然还需要对byte[]解密，这里跳过这步)
                int pos = 0;
                byte[] headLenBytes = new byte[4];
                Buffer.BlockCopy(data, pos, headLenBytes, 0, headLenBytes.Length);
                pos += headLenBytes.Length;
                int headSize = BitConverter.ToInt32(headLenBytes, 0);
                if (headSize < data.Length)
                {
                    byte[] headBytes = new byte[headSize];
                    Buffer.BlockCopy(data, pos, headBytes, 0, headBytes.Length);
                    pos += headBytes.Length;
                    headPack = ProtoBufUtils.Deserialize<MessagePack>(headBytes);

                    //解消息的内容
                    if (data.Length > pos)
                    {
                        int len = data.Length - pos;
                        content = new byte[len];
                        Buffer.BlockCopy(data, pos, content, 0, content.Length);
                        //内容数据放到具体Action业务上处理
                    }
                }
                else
                {
                    //不支持的数据格式
                }
            }
            catch (Exception ex)
            {
                //不支持的数据格式
            }
            return headPack;
        }

    }
}
